{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">原文地址 https://www.cnblogs.com/dingjiaoyang/p/11039359.html\n",
    "\n",
    "# ORM 概念\n",
    "\n",
    "ORM（Object Ralational Mapping，对象关系映射）用来把对象模型表示的对象映射到基于 S Q L 的关系模型数据库结构中去。这样，我们在具体的操作实体对象的时候，就不需要再去和复杂的 SQ L 语句打交道，只需简单的操作实体对象的属性和方法。O R M 技术是在对象和关系之间提供了一条桥梁，前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化  。\n",
    "\n",
    "# Python 中常用的 ORM \n",
    "\n",
    "## SQLObject\n",
    "\n",
    "SQLObject 是一种流行的对象关系管理器，用于为数据库提供对象接口，其中表为类，行为实例，列为属性。\n",
    "\n",
    "SQLObject 包含一个基于 Python 对象的查询语言，使 SQL 更抽象，并为应用程序提供了大量的数据库独立性。\n",
    "\n",
    "### 优点\n",
    "\n",
    "采用了易懂的 ActiveRecord 模式\n",
    "\n",
    "一个相对较小的代码库\n",
    "\n",
    "### 缺点\n",
    "\n",
    "方法和类的命名遵循了 Java 的小驼峰风格\n",
    "\n",
    "不支持数据库 session 隔离工作单元\n",
    "\n",
    "## Storm\n",
    "\n",
    "Storm 是一个介于 单个或多个数据库与 Python 之间 映射对象的 Python ORM 。为了支持动态存储和取回对象信息，它允许开发者构建跨数据表的复杂查询。Stom 中 table class 不需要是框架特定基类 的子类 。每个 table class 是 的 sqlobject.SQLObject 的子类。\n",
    "\n",
    "### 优点\n",
    "\n",
    "清爽轻量的 API，短学习曲线和长期可维护性  \n",
    "不需要特殊的类构造函数，也没有必要的基类  \n",
    "\n",
    "### 缺点\n",
    "\n",
    "迫使程序员手工写表格创建的 DDL 语句，而不是从模型类自动派生  \n",
    "Storm 的贡献者必须把他们的贡献的版权给 Canonical 公司  \n",
    "\n",
    "## Django's ORM\n",
    "\n",
    "因为 Django 的 ORM 是紧嵌到 web 框架的，所以就算可以也不推荐，在一个独立的非 Django 的 Python 项目中使用它的 ORM。\n",
    "\n",
    "Django，一个最流行的 Python web 框架， 有它独有的 ORM。 相比 SQLAlchemy， Django 的 ORM 更吻合于直接操作 SQL 对象，操作暴露了简单直接映射数据表和 Python 类的 SQL 对象 。\n",
    "\n",
    "### 优点\n",
    "\n",
    "易用，学习曲线短\n",
    "\n",
    "和 Django 紧密集合，用 Django 时使用约定俗成的方法去操作数据库\n",
    "\n",
    "### 缺点\n",
    "\n",
    "不好处理复杂的查询，强制开发者回到原生 SQL\n",
    "\n",
    "紧密和 Django 集成，使得在 Django 环境外很难使用\n",
    "\n",
    "## peewee \n",
    "\n",
    "### 优点\n",
    "\n",
    "Django 式的 API，使其易用\n",
    "\n",
    "轻量实现，很容易和任意 web 框架集成\n",
    "\n",
    "### 缺点\n",
    "\n",
    "不支持自动化 schema 迁移\n",
    "\n",
    "多对多查询写起来不直观\n",
    "\n",
    "## SQLAlchemy\n",
    "\n",
    "SQLAlchemy 采用了数据映射模式，其工作单元 主要使得 有必要限制所有的数据库操作代码到一个特定的数据库 session，在该 session 中控制每个对象的生命周期 。\n",
    "\n",
    "### 优点\n",
    "\n",
    "企业级 API，使得代码有健壮性和适应性\n",
    "\n",
    "灵活的设计，使得能轻松写复杂查询\n",
    "\n",
    "### 缺点\n",
    "\n",
    "工作单元概念不常见\n",
    "\n",
    "重量级 API，导致长学习曲线\n",
    "\n",
    "## GINO\n",
    "\n",
    "国人开发的较新的异步ORM框架，配合异步python Web框架（Tornado、aiohttp、Sanic、FastAPI/Starlette、Quart）能发挥出不错的性能。基于 MagicStack 出品必属精品的、一秒可读百万行的 asyncpg，以及 uvloop（可选）的强力加持，GINO 跑起来也是可以飞快的，被广泛应用于诸如实时汇率、聊天机器人、在线游戏等高并发领域，深受俄罗斯和乌克兰人民的爱戴。\n",
    "\n",
    "### 优点\n",
    "\n",
    "GINO 充分平衡了开发效率和明确性之间的辩证矛盾关系，基于SQLAlchemy core 开发，SQL查询语法与其相似，使得从SQLAlchemy 迁移到GINO容易很多。同时异步设计能使得系统性能上有所提升。\n",
    "\n",
    "\n",
    "### 缺点\n",
    "\n",
    "暂时只支持Postgresql，对其他生产环境支持度还不够。新生框架，社区文档都还不够完善，出现问题不容易得到解决；需要异步编程基础，对新手不够友好。\n",
    "\n",
    "\n",
    "# 总结  \n",
    "相比其他的 ORM， SQLAlchemy 意味着，无论你何时写 SQLAlchemy 代码， 都专注于工作单元的前沿概念 。DB Session 的概念可能最初很难理解和正确使用，但是后来你会欣赏这额外的复杂性，这让意外的时序提交相关的数据库 bug 减少到 0。在 SQLAlchemy 中处理多数据库是棘手的， 因为每个 DB session 都限定了一个数据库连接。但是，这种类型的限制实际上是好事， 因为这样强制你绞尽脑汁去想在多个数据库之间的交互， 从而使得数据库交互代码很容易调试"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "177.818px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
